package com.cn.web.user.service.impl;

import cn.hutool.crypto.digest.SM3;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cn.exception.MyException;
import com.cn.lock.MyRedisLockUtil;
import com.cn.user.UserDeviceDO;
import com.cn.util.ConstanUserUtil;
import com.cn.util.DateUtil;
import com.cn.web.user.mapper.IUserDeviceMapper;
import com.cn.web.user.service.UserDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * description: UserDeviceServiceImpl <br>
 * date: 23.7.10 11:52 <br>
 * author: cn_yaojin <br>
 * version: 1.0 <br>
 */
@Service
@Slf4j
public class UserDeviceServiceImpl implements UserDeviceService {

    @Autowired
    private IUserDeviceMapper userDeviceMapper;


    @Override
    public UserDeviceDO findByTokenId(String tokenId) {
        QueryWrapper<UserDeviceDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("token_id", tokenId);
        return this.userDeviceMapper.selectOne(queryWrapper);
    }

    @Override
    public UserDeviceDO findByDeviceId(UserDeviceDO info) {
        QueryWrapper<UserDeviceDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_id", info.getDeviceId());
        queryWrapper.eq("user_id", info.getUserId());
        return this.userDeviceMapper.selectOne(queryWrapper);
    }

    @Override
    public void add(UserDeviceDO info) throws InterruptedException {
        String key = "device:lock:" + info.getDeviceId();
        RLock rLock = MyRedisLockUtil.getFairLock(key);
        if (rLock.tryLock(2, 5, TimeUnit.SECONDS)) {
            try {
                QueryWrapper<UserDeviceDO> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("device_id", info.getDeviceId());
                queryWrapper.eq("user_id", info.getUserId());
                var userDevice = this.userDeviceMapper.selectOne(queryWrapper);
                Long id = null;
                if (userDevice == null) {
                    userDevice = new UserDeviceDO();
                } else {
                    id = userDevice.getId();
                }
                BeanUtils.copyProperties(info, userDevice);
                userDevice.setLoginTime(DateUtil.getTime());
                userDevice.setId(id);
                if (userDevice.getId() == null || userDevice.getId() <= 0) {
                    this.userDeviceMapper.insert(userDevice);
                } else {
                    this.userDeviceMapper.updateById(userDevice);
                }
            } finally {
                rLock.unlock();
            }

        } else {
            throw new MyException(ConstanUserUtil.REPEAT_ERROR);
        }
    }

    @Override
    public void delByDeviceId(String deviceId) {
        Map<String, Object> pd = new HashMap<>();
        pd.put("device_id", deviceId);
        this.userDeviceMapper.deleteByMap(pd);
    }

    @Override
    public void delByTokenId(String tokenId) {
        Map<String, Object> pd = new HashMap<>();
        pd.put("token_id", tokenId);
        this.userDeviceMapper.deleteByMap(pd);
    }
}
